﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using NodeBasedSkillEditor.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace NodeBasedSkillEditor.ViewModel
{
    public class VM_PortClusterGroup : ObservableObject
    {
        private string _clusterGroupName;
        public string ClusterGroupName {
            get { return _clusterGroupName; }
            set { _clusterGroupName = value; OnPropertyChanged(); }
        }

        public RelayCommand CreateNewClusterCmd { get; set; }

        public PortClusterGroup BindClusterGroupData { get; private set; }
        public uint LocalId {
            get => BindClusterGroupData.LocalId;
            set => BindClusterGroupData.LocalId = value;
        }
        public uint Id => DAGHelper.PortLocalId_To_PortGlobalId(ParentNode.LocalId, LocalId);

        public VM_Node ParentNode { get; private set; }
        public List<VM_PortCluster> Clusters { get; private set; } = new List<VM_PortCluster>();

        public PortClusterGroupControl BindCtrl { get; private set; }
        public UIElementCollection ClusterCtrlList => BindCtrl.ClusterStack.Children;

        public VM_PortClusterGroup(string clusterGroupName, PortClusterGroup bindData, VM_Node parentNode, PortClusterGroupControl bindCtrl)
        {
            CreateNewClusterCmd = new RelayCommand(CreateNewClusterAndCreateHistory);

            ClusterGroupName = clusterGroupName;
            ParentNode = parentNode;
            BindClusterGroupData = bindData;
            BindCtrl = bindCtrl;
            bindCtrl.DataContext = this;

            foreach (var c in bindData.Clusters)
            {
                CreateViewModelAndCtrlForClusterData(c);
            }
        }

        private void CreateNewClusterAndCreateHistory()
        {
            var newClusterVM = IncreaseCluster();
            ParentNode.ParentDAG.OnIncreasePortCluster(newClusterVM);
        }

        public VM_PortCluster IncreaseCluster()
        {
            var newClusterData = BindClusterGroupData.CreateNewCluster();
            var newClusterVM = CreateViewModelAndCtrlForClusterData(newClusterData);
            return newClusterVM;
        }

        public void DeleteCluster(VM_PortCluster clusterVM)
        {
            ClusterCtrlList.Remove(clusterVM.BindCtrl);
            Clusters.Remove(clusterVM);
            BindClusterGroupData.RemoveCluster(clusterVM.BindData);
            clusterVM.RemoveAllPortVmFromParentNodeAfterDelete();
            //BindClusterGroupData.Clusters.Remove(clusterVM.BindData);
        }

        public void DeleteLastIncreasedCluster()
        {
            var portClusterVM = Clusters[Clusters.Count -1];
            DeleteCluster(portClusterVM);
        }

        public void DeleteClusterAt(int index)
        {
            var portClusterVM = Clusters[index];
            DeleteCluster(portClusterVM);
        }

        public void InsertCluster(int index, PortCluster clusterData)
        {
            BindClusterGroupData.Clusters.Insert(index, clusterData);
            var portClusterCtrl = new PortClusterControl();
            ClusterCtrlList.Insert(index, portClusterCtrl);
            var portClusterVM = new VM_PortCluster(clusterData, portClusterCtrl, this);
            Clusters.Insert(index, portClusterVM);
        }

        VM_PortCluster CreateViewModelAndCtrlForClusterData(PortCluster clusterData)
        {
            var portClusterCtrl = new PortClusterControl();
            ClusterCtrlList.Add(portClusterCtrl);
            var portClusterVM = new VM_PortCluster(clusterData, portClusterCtrl, this);
            Clusters.Add(portClusterVM);
            return portClusterVM;
        }

    }
}
